/*
 * Copyright (c) 2012 swing-on-fire Team
 * 
 * This file is part of Swing-On-Fire (http://code.google.com/p/swing-on-fire), licensed under the terms of the MIT
 * License (MIT).
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
 * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
 * Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
package com.google.code.swingonfire.showcase.component.page.old;

import static com.google.code.swingonfire.builder.JComponentBuilders.*;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JTextArea;
import javax.swing.event.ChangeEvent;

import com.google.code.eventsonfire.Events;
import com.google.code.eventsonfire.awt.AWTEvents;
import com.google.code.eventsonfire.swing.SwingEventHandler;
import com.google.code.eventsonfire.swing.SwingEvents;
import com.google.code.swingonfire.border.ShadowBorder;
import com.google.code.swingonfire.component.JBorderPanel;
import com.google.code.swingonfire.component.page.old.JPagePane;
import com.google.code.swingonfire.component.page.old.JPagePaneBuilder;
import com.google.code.swingonfire.image.ImageCache;
import com.google.code.swingonfire.layout.GBC;
import com.google.code.swingonfire.plotter.ArrowSketch;
import com.google.code.swingonfire.plotter.Plotter;
import com.google.code.swingonfire.showcase.TitlePanel;

public class OldJPagePaneShowcase extends JPanel
{

    private static final long serialVersionUID = -1664314837619074615L;

    private final JPagePane pagePane;
    private final JComboBox animationFactoryComboBox;
    private final JTextArea descriptionArea;
    private final JSlider durationSlider;
    private final JButton previousButton;
    private final JButton nextButton;

    public OldJPagePaneShowcase()
    {
        super(new BorderLayout());

        pagePane = new JPagePaneBuilder().background(Color.BLACK).opaque(true).loopPages(true).build();

        animationFactoryComboBox =
            Events.bind(
                comboBoxBuilder().items(OldJPagePaneSamples.values()).selected(OldJPagePaneSamples.FADE_IN)
                    .listener("animationFactory", AWTEvents.fireOnAction()).opaque(false).build(), this);

        descriptionArea =
            textAreaBuilder().enabled(false).font(new Font(Font.MONOSPACED, Font.PLAIN, 10)).columns(40).rows(5)
                .lineWrap(true).wrapStyleWord(true).build();
        durationSlider =
            Events.bind(
                sliderBuilder().minimum(0).maximum(50).value(10).label(0, String.format("%,.1f s", 0.0))
                    .label(10, String.format("%,.1f s", 1.0)).label(20, String.format("%,.1f s", 2.0))
                    .label(30, String.format("%,.1f s", 3.0)).label(40, String.format("%,.1f s", 4.0))
                    .label(50, String.format("%,.1f s", 5.0)).majorTickSpacing(5).minorTickSpacing(1).snapToTicks(true)
                    .listener(SwingEvents.fireOnChange("duration")).opaque(false).build(), this);

        previousButton =
            Events.bind(
                buttonBuilder().text("Pg").listener("previous", AWTEvents.fireOnAction())
                    .opaque(false).build(), this);
        nextButton =
            Events.bind(buttonBuilder().listener("next", AWTEvents.fireOnAction()).opaque(false).build(), this);
        nextButton.setIcon(new Plotter(new ArrowSketch(1, 0.25, 0.5)).forComponent(nextButton).toIcon());

        new OldJPagePaneImageLoaderWorker(pagePane, "sample01").execute();
        new OldJPagePaneImageLoaderWorker(pagePane, "sample02").execute();
        new OldJPagePaneImageLoaderWorker(pagePane, "sample03").execute();
        new OldJPagePaneImageLoaderWorker(pagePane, "sample04").execute();
        new OldJPagePaneImageLoaderWorker(pagePane, "sample05").execute();
        new OldJPagePaneImageLoaderWorker(pagePane, "sample06").execute();

        JPanel valuePanel =
            panelBuilder().layout(new GridBagLayout()).border(BorderFactory.createEmptyBorder(8, 12, 8, 12))
                .background(Color.WHITE).opaque(true).build();
        GBC gbc = new GBC(5, 3);

        valuePanel.add(labelBuilder().text("Animation:").labelFor(animationFactoryComboBox).build(), gbc.right());
        valuePanel.add(animationFactoryComboBox, gbc.next());
        valuePanel.add(new JLabel(), gbc.next().weight(1));
        valuePanel.add(previousButton, gbc.next().insetRight(2));
        valuePanel.add(nextButton, gbc.next().insetLeft(2));
        valuePanel.add(labelBuilder().text("Description:").labelFor(descriptionArea).build(), gbc.next().top().right());
        valuePanel.add(new JScrollPane(descriptionArea), gbc.next().hFill().weight(1).span(4));
        valuePanel.add(labelBuilder().text("Duration:").labelFor(durationSlider).build(), gbc.next().right());
        valuePanel.add(durationSlider, gbc.next().hFill().weight(1).span(4));

        add(new JBorderPanel(new TitlePanel("JPagePane / JPageViewport", "A paged panel with animation effects"),
            ShadowBorder.create()), BorderLayout.NORTH);
        add(new JBorderPanel(pagePane, ShadowBorder.create()), BorderLayout.CENTER);
        add(new JBorderPanel(valuePanel, ShadowBorder.create()), BorderLayout.SOUTH);

        updateState();
        updateAnimationFactory();
    }

    public double getDuration()
    {
        return durationSlider.getValue() / 10d;
    }

    public void updateState()
    {
        OldJPagePaneSamples item = (OldJPagePaneSamples) animationFactoryComboBox.getSelectedItem();

        descriptionArea.setText(item.getFullDescription());
    }

    public void updateAnimationFactory()
    {
        OldJPagePaneSamples item = (OldJPagePaneSamples) animationFactoryComboBox.getSelectedItem();

        pagePane.setAnimationFactoryForPrevious(item.getAnimationFactoryForPrevious(getDuration()));
        pagePane.setAnimationFactoryForNext(item.getAnimationFactoryForNext(getDuration()));
    }

    @SwingEventHandler(event = ActionEvent.class, eachTag = "animationFactory")
    public void onAnimationFactory()
    {
        updateState();
        updateAnimationFactory();
    }

    @SwingEventHandler(event = ChangeEvent.class, eachTag = "duration")
    public void onDuration()
    {
        updateState();
        updateAnimationFactory();
    }

    @SwingEventHandler(event = ChangeEvent.class, eachTag = "pause")
    public void onPause()
    {
        updateState();
        updateAnimationFactory();
    }

    @SwingEventHandler(event = ActionEvent.class, eachTag = "previous")
    public void onPrevioius()
    {
        int index = pagePane.getSelectedComponentIndex();

        if (index < 0)
        {
            return;
        }

        pagePane.setSelectedComponent(((index + pagePane.getComponentCount()) - 1) % pagePane.getComponentCount());
    }

    @SwingEventHandler(event = ActionEvent.class, eachTag = "next")
    public void onNext()
    {
        int index = pagePane.getSelectedComponentIndex();

        if (index < 0)
        {
            return;
        }

        pagePane.setSelectedComponent((index + 1) % pagePane.getComponentCount());
    }

}
